package com.study.talk.data.net

import android.util.Log
import com.study.talk.di.AppModule
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.io.IOException

object OkHttp {

    private const val TAG = "OkHttp"

    private val URL = AppModule.getWebUrl()
    private val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()

    fun get(url: String, error: (String) -> Unit, success: (String) -> Unit) {
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).get().build()
        sendRequest(request, success, error)
    }


    fun post(url: String, gson: String, error: (String) -> Unit, success: (String) -> Unit) {
        Log.d(TAG, "post: $gson")
        val body = gson.toRequestBody("application/json".toMediaTypeOrNull())
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).post(body).build()
        sendRequest(request, success, error)
    }

    fun delete(url: String, gson: String, error: (String) -> Unit, success: (String) -> Unit) {
        val body = gson.toRequestBody("application/json".toMediaTypeOrNull())
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).delete(body).build()
        sendRequest(request, success, error)
    }

    fun delete(url: String, error: (String) -> Unit, success: (String) -> Unit) {
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).delete().build()
        sendRequest(request, success, error)
    }


    fun put(url: String, gson: String, error: (String) -> Unit, success: (String) -> Unit) {
        Log.d(TAG, "put: $gson")
        val body = gson.toRequestBody("application/json".toMediaTypeOrNull())
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).put(body).build()
        sendRequest(request, success, error)
    }

    fun put(url: String, error: (String) -> Unit, success: (String) -> Unit) {
        val request = Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken())
            .put("".toRequestBody("application/json".toMediaTypeOrNull())).build()
        sendRequest(request, success, error)
    }


    fun postFile(url: String, path: String, error: (String) -> Unit, success: (String) -> Unit) {
        val file = File(path)
        val body = file.asRequestBody("image/*".toMediaTypeOrNull())
        val multipartBody = MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("mFile", file.name, body).build()
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken()).post(multipartBody)
                .build()

        sendRequest(request, success, error)
    }

    fun uploadFiles(
        url: String, paths: List<String>, error: (String) -> Unit, success: (String) -> Unit
    ) {
        val multipartBody = MultipartBody.Builder().setType(MultipartBody.FORM)
        paths.forEach { path ->
            File(path).let {
                multipartBody.addFormDataPart(
                    "files", it.name, it.asRequestBody("image/*".toMediaTypeOrNull())
                )
            }
        }
        val request =
            Request.Builder().url(URL + url).addHeader("Authorization", AppModule.getToken())
                .post(multipartBody.build())
                .build()
        sendRequest(request, success, error)
    }

    private fun sendRequest(request: Request, success: (String) -> Unit, error: (String) -> Unit) {
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                error("请求失败！")
            }

            @Throws(IOException::class)
            override fun onResponse(call: Call, response: Response) {
                response.body?.let {
                    success.invoke(it.string())
                }
            }
        })
    }
}